import sys
# import resource
from learning.StatePrefixEqOracleFailSafe import StatePrefixOracleFailSafe
from learning.FailSafeCacheSUL import FailSafeCacheSUL, print_error_info
from learning.Lstar import ju_run_Lstar
from aalpy.utils import visualize_automaton
from pesp4.IKESUL import *
import DBhelper
import shutil,utils
from learning.Errors import NonDeterministicError
args_len = len(sys.argv) - 1

if args_len < 5:
    sys.exit("Too few arguments provided.\nUsage: python3 ipsec_learning.py 'version' 'local_ip' 'remote_ip' 'iface' 'object' 'out_dir'")


# python ipsec_learning.py v2 192.168.38.1 192.168.38.134 'VMware Virtual Ethernet Adapter for VMnet8' strongswan IKEv2_learning_strongswan
IKE_version = sys.argv[1]
local_ip = sys.argv[2]
remote_ip = sys.argv[3]
iface = sys.argv[4]
object = sys.argv[5]
out_dir = sys.argv[6]

if os.path.exists(out_dir):
    shutil.rmtree(out_dir)
os.makedirs(out_dir)
    
learned_model_name = f'{out_dir}/learned_model_strongswan'

ike_sul = IKESUL(local_ip, remote_ip, iface=iface, version=IKE_version, object=object, dir=out_dir)

if IKE_version == 'v1':
    alphabet = ['main_mode_1', 'main_mode_2', 'main_mode_3', 'quick_mode_1',  'quick_mode_2', 'delete_ESP', 'delete_IKE']
else:
    # alphabet = ['SAINIT_SA-KE-NONCE', 'AUTH_IDi-AUTH-SA-TSi-TSr', 'CHILDSA_SA-NONCE-TSi-TSr', 'CHILDSA_RekeyIKE-KE-NONCE', 'OI_CHILDSA_SA-NONCE-TSi-TSr', 'OI_INFO_DelIKE', 'CHILDSA_RekeySA-SA-NONCE-TSi-TSr', 'test_ipsec', 'test_old_ipsec', 'INFO_DelOldChild', 'INFO_DelChild', 'INFO_', 'INFO_DelIKE']
    # alphabet = ['SAINIT_SA-KE-NONCE', 'AUTH_IDi-AUTH-SA-TSi-TSr', 'CHILDSA_SA-NONCE-TSi-TSr', 'CHILDSA_RekeySA-SA-NONCE-TSi-TSr', 'test_ipsec', 'INFO_DelIKE']
    alphabet = ['CHILDSA_RekeySA-SA-NONCE-TSi-TSr', 'SAINIT_SA-KE-NONCE', 'INFO_DelIKE']




sul = FailSafeCacheSUL(ike_sul, database=f'learning/database/{out_dir}.db')

# define a equivalence oracle
eq_oracle = StatePrefixOracleFailSafe(alphabet, sul, walks_per_state=20, walk_len=10, database=f'learning/database/{out_dir}.db')

# run the learning algorithm
# internal caching is disabled, since we require an error handling for possible non-deterministic behavior+


learned_model = ju_run_Lstar(alphabet, sul, eq_oracle, automaton_type='mealy',db_path=f'learning/database/{out_dir}.db', cache_and_non_det_check=False, print_level=3)


# visualize the automaton
# visualize_automaton(learned_model, path=learned_model_name, file_type='dot')

# # prints number of connection and non-deterministic errors
# print_error_info(sul)
